iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 7
1

引言

當兩個二維的點p1, p2已決定,而我們也知道像素點是不連續的,這時該怎麼在這兩個點中間填上適合的點,讓他們看起來像是由p1, p2連起來的直線呢?

這時我們會使用到由像素點繪製直線用的DDA演算法,這是個相對簡便好理解的直線繪製演算法,我們就使用這個演算法來繪製直線吧!


DDA演算法

演算法的想法與步驟我將列在底下:

DDA演算法的想法是,將x, y分量差較大者當作總像素點數(例如國中學過的邊長3,4,5直角三角形,5那邊是連起來的線,3, 4則分別是x, y分量,則此處邊長為4的邊就是分量差較大者),這樣能確保這條線每個點間都能相連。另一方面,先計算好要的線的斜率,然後在每個相鄰的點都累加這個斜率,就能畫出線了。這個方法能確保每個點之間都只使用到加法,畢竟斜率在一開始就計算好了,計算量較少。大家可能會想問為什麼想讓計算量減少呢?畢竟想要在螢幕上高頻率地更新畫面,可是牽涉到非常多的線條改動,試想如果是個高畫質的3D遊戲,線條可能是以百萬條計算,要在極短時間內更新幾百萬條線條的狀態,計算量可就大了許多。因此減少最基本元素的計算量是很重要的呢。

  1. 決定兩點p1, p2以及兩點x, y分量的差(以下簡稱dx, dy)
  2. 判斷由x, y連起來的直線是「平緩的 Gentle」或是「急劇的 Sharp」。平緩的定義是dx的大小大於dy的大小;急劇的定義是dy的大小大於dx的大小。
    https://ithelp.ithome.com.tw/upload/images/20190904/20111429H1a3mS7Vf1.png
    https://ithelp.ithome.com.tw/upload/images/20190904/20111429U87JKmXGrz.png
    https://ithelp.ithome.com.tw/upload/images/20190904/20111429AvpaQg9Kf8.png
  3. 若確定是平緩的直線,則把總像素點數設為dx(因為dx比較大),反之則總像素點數設為dy。
  4. 我們可以把畫線當作爬山,總像素點數我們當作總步數(stepNumber),一共要走幾步才能畫完這條線。以前面的3,4,5三角形為例,4是總步數,因此我們要繪製4個像素點才能畫完這條線。
  5. 再來我們計算每一步要走多長,有了總山路長度(dx, dy的比擬),也有了總步數,我們可以算出x, y每一步要走多長(分別設為xStepLenyStepLen),式子如下:
    https://chart.googleapis.com/chart?cht=tx&chl=xStepLen%20%3D%20%5Cfrac%7Bdx%7D%7BstepNumber%7D
    https://chart.googleapis.com/chart?cht=tx&chl=yStepLen%20%3D%20%5Cfrac%7Bdy%7D%7BstepNumber%7D
  6. 得到了每步的距離後,由第一個點開始畫(通常是p1或p2其中之一),而後分別將x, y分量加上xStepLen與yStepLen,得到第二個點,但此點通常是帶有小數點的浮點數,需要先經過四捨五入處理,成為整數點,再畫上去,不斷重複直到每個點都畫上去(一共有 總步數+1 個像素點哦!)。
  7. 演算法結束。

以3,4,5三角形為例:
https://ithelp.ithome.com.tw/upload/images/20190904/20111429pGIIrQPUOD.png

下篇我們將實際以C語言實作這個演算法。


上一篇
[11屆鐵人賽Day6] C語言實作—3維座標投影2維座標
下一篇
[11屆鐵人賽Day8] DDA演算法—C語言實作
系列文
若沒有遊戲引擎、合作夥伴...做得出遊戲嗎? 不試試看不知道吧? [使用C語言]30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言